﻿using System.Collections;

namespace PrototypePattern
{
    /// <summary>
    /// 原型管理器-PrototypeManager
    /// </summary>
    class PrototypeManager
    {
        #region SingleProfit 单例模式
        //创建私有化静态obj锁
        private static readonly object _ObjLock = new object();
        //创建私有静态字段，接收类的实例化对象
        private static volatile PrototypeManager _SingleProfit = null; //volatile 促进线程安全，保证线程有序执行 
        //构造函数私有化
        private PrototypeManager() { }
        //创建单利对象资源并返回
        public static PrototypeManager CreateSingleProfitObj()
        {
            if (_SingleProfit == null)
            {
                lock (_ObjLock)
                {
                    if (_SingleProfit == null)
                    {
                        _SingleProfit = new PrototypeManager();
                    }
                }
            }
            return _SingleProfit;
        } 
        #endregion

        /// <summary>
        /// Hashtable 存储原型对象
        /// </summary>
        private readonly static Hashtable hashTable = new Hashtable();

        /// <summary>
        /// Hashtable 新增原型对象
        /// </summary>
        /// <param name="key"></param>
        /// <param name="prototype"></param>
        public void Add(string key, Prototype prototype) 
        {
            hashTable.Add(key,prototype);
        }

        /// <summary>
        /// 获取克隆对象
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Prototype Get(string key) 
        {
            Prototype copy = ((Prototype)hashTable[key]).Clone(); //通过（内置）克隆方法创建新对象
            return copy;
        }
    }


    #region 配合 PrototypeManager 使用
    class ConcretePrototypeC : Prototype
    {
        public override Prototype Clone()
        {
            return (ConcretePrototypeC) this.MemberwiseClone();
        }
    }

    class ConcretePrototypeD : Prototype
    {
        public override Prototype Clone()
        {
            return (ConcretePrototypeD) this.MemberwiseClone();
        }
    }
    #endregion
}
